package org.luo.lan.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.luo.lan.server.config.ServerConfig;
import org.luo.lan.server.factory.BridgeChannelFactory;
import org.luo.lan.server.initializers.BridgeServerInitializers;
import org.luo.lan.server.initializers.DomainServerInitializer;

/**
 * @Auther: luobiao
 * @Date: 2020/9/19 09:15
 * @Description:
 */
@Slf4j
public class ServerApplication {
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;

    public static void main(String[] args) {
        new ServerApplication();
    }

    private ServerApplication() {
        start();
    }

    public void start() {
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        bindServerPort(new BridgeServerInitializers(), ServerConfig.getInstance().getBridgePort()).addListener((ChannelFuture future) -> {
            if (future.isSuccess()) {
                log.debug("服务器端桥接端口启动成功！");
                BridgeChannelFactory.INSTANCE.setApplication(this);
                //启动域名代理端口
                bindServerPort(new DomainServerInitializer(), ServerConfig.getInstance().getDomainProxyPort()).addListener((ChannelFuture domainFuture) -> {
                    if (domainFuture.isSuccess()) {
                        log.debug("服务器端域名代理端口启动成功！");
                    } else {
                        log.error("服务器端域名代理端口启动失败！失败原因：{}", domainFuture.cause().getMessage());
                    }
                });
            } else {
                log.error("服务器端桥接端口启动失败！失败原因：{}", future.cause().getMessage());
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
                log.info("应用关闭中...");
            }
        });
    }

    public ChannelFuture bindServerPort(ChannelInitializer initializer, int port) {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        return serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(initializer)
                .bind(port);
    }
}
